#ifndef ASYNC_LOGGER_H
#define ASYNC_LOGGER_H
#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include <iomanip>
#include <mutex>
#include <thread>
#include <atomic>
#include <vector>
#include <cstring>
#include <memory>

class AsyncLogger {
public:
    // 初始化日志系统（建议程序启动时调用）
    static void Init(const std::string& filename) {
        std::lock_guard<std::mutex> lock(init_mutex);
        if (!instance) {
            instance = new AsyncLogger(filename);
        }
    }

    // 获取单例实例
    static AsyncLogger& GetInstance() {
        std::call_once(init_flag, [] {
            if (!instance) Init("app.log");
            });
        return *instance;
    }

    // 流式写入接口
    class LogStream {
    public:
        LogStream(const char* file, int line, const char* func)
            : stream(std::make_shared<std::ostringstream>())
        {
            auto now = std::chrono::system_clock::now();
            auto time = std::chrono::system_clock::to_time_t(now);

            // 使用线程局部缓冲区避免重复分配
            thread_local char time_buf[20];
            std::strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", std::localtime(&time));

            *stream << time_buf << " ";
            *stream << std::this_thread::get_id() << " ";
            *stream << file << ":" << line << " (" << func << ") ";
        }

        ~LogStream() {
            if (!stream) return;

            // 写入线程局部缓冲区
            auto& buffer = GetThreadLocalBuffer();
            std::lock_guard<std::mutex> lock(buffer_mutex);
            buffer << stream->str() << std::endl;

            // 达到阈值时触发写入
            if (buffer.tellp() >= static_cast<std::streampos>(BUFFER_SIZE)) {
                FlushInternal(buffer);
            }
        }

        template<typename T>
        LogStream& operator<<(const T& data) {
            if (stream) *stream << data;
            return *this;
        }

        LogStream& operator<<(std::ostream& (*manip)(std::ostream&)) {
            if (stream) manip(*stream);
            return *this;
        }

        // 手动刷新当前线程缓冲区
        static void Flush() {
            auto& buffer = GetThreadLocalBuffer();
            std::lock_guard<std::mutex> lock(buffer_mutex);
            FlushInternal(buffer);
        }

    private:
        std::shared_ptr<std::ostringstream> stream;
        static constexpr size_t BUFFER_SIZE = 4096; // 4KB缓冲区

        static std::ostringstream& GetThreadLocalBuffer() {
            thread_local std::ostringstream tls_buffer;
            return tls_buffer;
        }

        static void FlushInternal(std::ostringstream& buffer) {
            if (buffer.tellp() == 0) return;

            // 双重检查锁定确保线程安全
            auto& logger = GetInstance();
            std::lock_guard<std::mutex> lock(logger.file_mutex);
            logger.logFile << buffer.str();
            buffer.str("");
        }
    };

private:
    AsyncLogger(const std::string& filename) {
        logFile.open(filename, std::ios::app);
        if (!logFile.is_open()) {
            std::cerr << "Failed to open log file: " << filename << std::endl;
            abort();
        }
    }

    ~AsyncLogger() {
        // 程序退出时刷新所有缓冲区（需要更完整的实现）
        logFile.close();
    }

    static inline std::once_flag init_flag{};
    static inline AsyncLogger* instance = nullptr;
    std::ofstream logFile;
    static inline std::mutex init_mutex;
    static inline std::mutex buffer_mutex;
    static inline std::mutex file_mutex;

};

// 定义日志宏
#define LOG_v1 AsyncLogger::LogStream(__FILE__, __LINE__, __FUNCTION__)
#define BATCH_LOG LOG_v1 // 此实现下所有日志自动批量处理

// 确保程序退出时刷新缓冲区
struct LogTerminator {
    ~LogTerminator() {
        AsyncLogger::LogStream::Flush();
    }
} static log_terminator;

#endif // ASYNC_LOGGER_H